###########################################################################
# 交通仿真程序主窗口
# 作者：张立业
# Copyright: 山东科技大学，交通学院。 All right reserved.
#
##########################################################################

import simulate
from ui_mainwindow import Ui_MainWindow
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

from simulate import *
from car import *
from trafficlight import TrafficLight
from mapview import MapView
import config
import pub

class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__( )       #调用父类的构造函数
        self.setupUi( self )      #设置GUI
        config.mainwnd = self

        self.mLights = []         #所有信号灯
        self.mActStart.triggered.connect( self.actStartSim )    # 关联菜单项与相应的函数
        self.mActionCreateRoute.triggered.connect( self.actCreateRoute )

        # 加入地图窗口
        self.mScene = QGraphicsScene()
        self.mSimView = MapView( self.mScene )     #地图窗口
        self.mSimView.mMainWnd = self
        self.mVerticalLayout.insertWidget(1, self.mSimView)

        # 调整缩放系数
        self.mVerticalLayout.setStretchFactor( self.mSimView, 1 )
        self.mVerticalLayout.setStretchFactor(self.mEditSimOutput, 0)

        # 创建计时器对象
        self.mTimer = QTimer(self)
        self.mTimer.timeout.connect( self.nextStep )
        self.mT = 0     # 仿真时间
        self.mCars = []
        self.mToolState = pub.ToolState.NONE       #

        self.createUI()

    def createUI(self):
        ## 仿真控制工具条
        mToolBarSim = QToolBar("Simulation toolbar")

        # toolbar button: start
        self.mToolBtStart = QToolButton()
        # self.mToolBtPane.setDefaultAction(self.mActionPanView)
        self.mToolBtStart.setToolTip('交通学院仿真开始')
        button_icon = QIcon(config.g_base_dir + "/image/start.PNG")
        self.mToolBtStart.setIcon(button_icon)
        mToolBarSim.addWidget(self.mToolBtStart)

        # toolbar button: step
        self.mToolBtStep = QToolButton()
        # self.mToolBtPane.setDefaultAction(self.mActionPanView)
        self.mToolBtStep.setToolTip('开始仿真')
        button_icon = QIcon(config.g_base_dir + "/image/step.PNG")
        self.mToolBtStep.setIcon(button_icon)
        mToolBarSim.addWidget(self.mToolBtStep)

        # toolbar button: step
        self.mToolBtStop = QToolButton()
        # self.mToolBtPane.setDefaultAction(self.mActionPanView)
        self.mToolBtStop.setToolTip('开始仿真')
        button_icon = QIcon(config.g_base_dir + "/image/stop.PNG")
        self.mToolBtStop.setIcon(button_icon)
        mToolBarSim.addWidget(self.mToolBtStop)

        self.addToolBar(Qt.TopToolBarArea, mToolBarSim)

        #######################################################################
        ## 路网浏览工具条
        mToolBarView = QToolBar("View scale toolbar")

        # toolbar button: pan
        self.mToolBtPane = QToolButton()

        self.mActionPan = QAction()
        self.mActionPan.triggered.connect(self.actPan)
        self.mToolBtPane.setDefaultAction(self.mActionPan)
        self.mToolBtPane.setToolTip('pan the map')
        button_icon = QIcon( config.g_base_dir + "/image/scale_pan.PNG" )
        self.mToolBtPane.setIcon(button_icon)
        mToolBarView.addWidget(self.mToolBtPane)


        # toolbar button: enlarge
        self.mToolBtScaleWindow = QToolButton()
        # self.mToolBtScaleWindow.setDefaultAction(self.mActionRectangleView)
        self.mToolBtScaleWindow.setToolTip('Zoom to selection')
        button_icon = QIcon( config.g_base_dir + "/image/scale_window.PNG")
        self.mToolBtScaleWindow.setIcon(button_icon)
        mToolBarView.addWidget(self.mToolBtScaleWindow)

        self.addToolBar(Qt.TopToolBarArea, mToolBarView)

        ## 左侧路网编辑工具条
        mToolBarMap = QToolBar("Map Editor toolbar")

        # toolbar button: enlarge
        self.mToolBtAddRout = QToolButton()
        # self.mToolBtScaleWindow.setDefaultAction(self.mActionRectangleView)
        self.mToolBtAddRout.setToolTip('Zoom to selection')
        button_icon = QIcon(config.g_base_dir + "/image/node.png")
        self.mToolBtAddRout.setIcon(button_icon)
        mToolBarMap.addWidget(self.mToolBtAddRout)

        self.mToolBtAddLight = QToolButton()
        self.mActionAddLight = QAction()
        self.mActionAddLight.triggered.connect( self.actAddTrafficLight )

        self.mToolBtAddLight.setDefaultAction( self.mActionAddLight )
        self.mToolBtAddLight.setToolTip('Zoom to selection')
        button_icon = QIcon(config.g_base_dir + "/image/light.PNG")
        self.mToolBtAddLight.setIcon(button_icon)
        mToolBarMap.addWidget(self.mToolBtAddLight)

        self.mToolBtAddDetector = QToolButton()
        # self.mToolBtScaleWindow.setDefaultAction(self.mActionRectangleView)
        self.mToolBtAddDetector.setToolTip('Zoom to selection')
        button_icon = QIcon(config.g_base_dir + "/image/detector.PNG")
        self.mToolBtAddDetector.setIcon(button_icon)
        mToolBarMap.addWidget(self.mToolBtAddDetector)

        self.addToolBar(Qt.LeftToolBarArea, mToolBarMap)

    def actAddTrafficLight(self):
        self.mEditSimOutput.append( "Map Tool is set to : Adding traffic light" )
        self.mToolState = pub.ToolState.ADD_LIGHT

    def nextStep(self):
        '''相应时间事件

        '''
        ## 时间推移，更新所有车的状态
        self.mT += 1
        self.mEditSimOutput.append( "Sim Time: " + str(self.mT) )

        for car in self.mCars:
            if (self.mT >= car.start_time) and (car.running is False):  # 判断已经进入路段
                car.show()
                car.run()

            if car.pos >= 1000:  # 到达路段终点
                car.hide()
            else:
                car.setPos(car.pos, 2)   # 更新车辆位置信息

        # 更新交通灯的状态
        for lt in self.mLights:
            st = random.randint(0, 3)
            lt.setState( st )

        # ## start simulate
        # for t in range(sim_t):
        #     for c in cars:
        #         c.run()
        #
        #         # start_sim()
        # sim_rst += "Simulation Ended"

    def actStartSim(self):
        self.mTimer.start( 500 )  # time interval

        rst = self.create_cars()
        self.mEditSimOutput.append(rst)

    def actCreateRoute(self):
        '''
        生成路网
        '''
        segment = QGraphicsRectItem(0, 0, 1000, 40)   #路段宽度1000
        segment.setBrush( QBrush(Qt.gray) )
        self.mScene.addItem(segment)

        # 添加道路中间线
        segment = QGraphicsLineItem(0, 20, 1000, 20)  # 路段宽度1000
        segment.setPen( QPen(Qt.yellow) )
        self.mScene.addItem(segment)

        # 车道分割线
        line = QGraphicsLineItem(0, 10, 1000, 10)  # 路段宽度1000
        pen = QPen(Qt.white)
        pen.setStyle( Qt.DashLine )
        line.setPen( pen )
        self.mScene.addItem(line)

        line = QGraphicsLineItem(0, 30, 1000, 30)  # 路段宽度1000
        pen = QPen(Qt.white)
        pen.setStyle(Qt.DashLine)
        line.setPen(pen)
        self.mScene.addItem(line)

        ## 添加路段2
        segment = QGraphicsRectItem(1000, -250, 40, 500)  # 路段宽度1000
        segment.setBrush(QBrush(Qt.gray))
        self.mScene.addItem(segment)

        segment = QGraphicsLineItem(1020, -250, 1020, 250)  # 路段宽度1000
        segment.setPen(QPen(Qt.yellow))
        self.mScene.addItem(segment)

        # 添加车道线
        line = QGraphicsLineItem(1010, -250, 1010, 250)  # 路段宽度1000
        pen = QPen(Qt.white)
        pen.setStyle(Qt.DashLine)
        line.setPen(pen)
        self.mScene.addItem(line)

        line = QGraphicsLineItem(1030, -250, 1030, 250)  # 路段宽度1000
        pen = QPen(Qt.white)
        pen.setStyle(Qt.DashLine)
        line.setPen(pen)
        self.mScene.addItem(line)

        self.createTrafficLight()


    def create_cars(self):
        """
            路段交通仿真

            返回值：结果的字符串
        """
        sim_rst = ""
        # print("Simulation started")
        sim_rst += "Simulation started\n"
        head_t = 0
        for i in range(50):
            car = Car(i)
            car.set_size(0, 2, 8, 4)
            car.setPos(0, 0)
            head_t += random.randint(0,10)
            car.start_time = head_t
            car.set_rand_color()
            car.hide()
            self.mCars.append( car )
            self.mScene.addItem( car )

        # print(len(cars), " cars are created.")
        sim_rst += str(len(self.mCars)) + " cars are created." + "\n"
        for c in self.mCars:
            # print("Car name: ", c.id, " position is: ", c.pos, " start time: ", c.start_time)
            sim_rst += "Car name: " + str(c.id) + " position is: " + str(c.pos) + " start time: " + str(
                c.start_time) + "\n"

        return sim_rst

    def createTrafficLight(self):
        light = TrafficLight( self.mScene, 0, -55 )
        light.setState( 2 )
        self.mLights.append(light)

        light = TrafficLight(self.mScene, 950, -55)
        light.setState(2)
        self.mLights.append(light)

        light = TrafficLight(self.mScene, 1050, -55)
        light.setState(0)
        self.mLights.append(light)

        light = TrafficLight(self.mScene, 1050, 30)
        light.setState(1)
        self.mLights.append(light)

        segment = QGraphicsRectItem(500, -10, 20, 60)  # 路段宽度1000
        self.mScene.addItem(segment)


    def actPan(self):
        self.mEditSimOutput.append("Map Tool is set to : Pan")
        self.mToolState = pub.ToolState.PAN

